/*
 * MCR.c
 *
 *  Created on: 05/08/2013
 *      Author: marcio
 */

#include <MCR.h>

WORD* curbitR;
long* curR;
long* cc;
long cl;
long curv;
WORD* RR;
WORD* auxR;

void* mcrAloca(){
	SPMCR* sub = (SPMCR*)malloc(sizeof(SPMCR));
	sub->R = (long*)malloc(sizeof(long)*gn);
	sub->bitR = (WORD*)malooc(sizeof(WORD)* ((gn >> b_logW) + 1));
	setAllToCompl(sub->bitR, gn);
	sub->cover = (long*)malloc(sizeof(long)*gn);
	sub->dp = 0;
	sub->r = 0;
	return (void*)sub;
}

void mcrRelease(void* s){
	SPMCR* sp = (SPMCR*)s;
	free(sp->R);
	free(sp->bitR);
	free(sp->cover);
	free(sp);
}

int mcrSel(void* s, long lim){
	SPMCR* sp = (SPMCR*)s;
	if(sp->p >= 0){
		curbitR = sp->bitR;
		curR = sp->R;
		cc = sp->cover;
		cl = sp->dp;
		curv = sp->R[sp->p];
		return sp->cover[sp->p--] + sp->dp > lim;
	}else return 1;
}

int mcrRoot(void* s){
	SPMCR* sp = (SPMCR*)s;
	setAlltoSet(sp->bitR);
	long deg = 0;
	long maxdeg = 0;
	long i;
	for(i = 0; i < gn; i++){
		sp->R[i] = i;
		deg = degree(i);
		maxdeg = deg > maxdeg? deg: maxdeg;
	}

	for(i = 0; i <= maxdeg; i++)
		sp->cover[i] = i;

	for(i = maxdeg+1; i < gn; i++)
		sp->cover[i] = maxdeg+1;

}


int mcrGen(void* s, long* num){
	SPMCR* sp = (SPMCR*)s;
	long null = setIntersec(sp->bitR, neig(curv),0, gn);
	sp->dp = cl +1;
	long v,u;
	long color = 0;
	long r = 0;
	if(null){
		if(sp->dp > *num) *num = sp->dp;
		return 1;
	}
	else{
		setAllToCompl(auxR,gn);
		setCopy(sp->bitR, RR);
		v = 0;
		while((v = setNextOf(RR, v)) < gn){
			sp->R[r] = v;
			sp->cover[r++] = color;
			setToCompl(RR, v);
			setCopy(RR, auxR);
			u = 0;
			while((u = setNextOf(auxR, u)) < gn){
				sp->R[r] = u;
				sp->cover[r++] = color;
				setToCompl(auxR, u);
				setIntersec(auxR, auxR, neig(u), u, gn);
			}
			color++;
		}
		sp->r = r;
		sp->p = r-1;
	}
}
